#include <stdlib.h>
#include <stdio.h>
#include "Pc.h"
#include "common.h"

#ifdef _WIN32
#ifdef _DEBUG
   #include <crtdbg.h>
   #undef THIS_FILE
   static char THIS_FILE[] = __FILE__;
   #define new       new( _NORMAL_BLOCK, __FILE__, __LINE__)
   #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#endif

Pc::Pc(int id, HANDLE hMutex, MYSQL *db_link) {
	MYSQL_RES *rSelect;
	MYSQL_ROW row;
	char query[DEFAULT_BUFLEN];
	
	this->hMutex = hMutex;
	this->db_link = db_link;

	sprintf(query, "SELECT name, isHidden FROM n_wb_pc WHERE id = %d", id);
//	printf("query is '%s'\n", query);

	// -- Thread-Safe Mysql call --
	// Request ownership of mutex
	WaitForSingleObject(this->hMutex, INFINITE);
	// Make mysql calls which need Mutex protection
	mysql_query(this->db_link, query);
	rSelect = mysql_store_result(this->db_link);
	// Release the mutex
	ReleaseMutex(this->hMutex);

	if(rSelect) {
		if(row = mysql_fetch_row(rSelect)) {
			this->id = id;
			this->netbios = _strdup(row[0]);
			this->isHidden = atoi(row[1]);
		}
		// free up the result from the mysql query
		mysql_free_result(rSelect);
	}
}

Pc::~Pc(void) {
	delete[] this->netbios;
}

// set a detail
// use the table 'n_wb_pc_%d_0' (netbios_id) to look up the 'list' name & get the id associated
// then use the table 'n_wb_pc_%d_%d' (netbios_id, list_id) to perform set/get operations
// if list == NULL, then the default table will be used
bool Pc::set(char *list, char *data, char *value) {
	MYSQL_RES *rSelect, *rUpdate;
	MYSQL_ROW row;
	char query[DEFAULT_BUFLEN];
	char *table;

	// allocate table name to work with
	if(list == NULL) {
		table = _strdup("default");
	}
	else {
		table = _strdup(list);		
	}

//	printf("data = '%s'\n", data);
//	printf("value = '%s'\n", value);
//	printf("table = '%s'\n", table);
//	printf("id = '%d'\n", this->id);

	// query for the table_id
	sprintf(query, "SELECT id FROM n_wb_pc_%d WHERE record LIKE \"%%%s%%\"", this->id, table);
//	printf("query is '%s'\n", query);

	// -- Thread-Safe Mysql call --
	// Request ownership of mutex
	WaitForSingleObject(this->hMutex, INFINITE);
	// Make mysql calls which need Mutex protection
	mysql_query(this->db_link, query);
	rSelect = mysql_store_result(this->db_link);
	// Release the mutex
	ReleaseMutex(this->hMutex);

	int table_id = 0;
	if(rSelect) {
		if(row = mysql_fetch_row(rSelect)) {
			table_id = atoi(row[0]);
		}

		// free up the result from the mysql query
		mysql_free_result(rSelect);
	}

//	printf("table_id is %d\n", table_id);

	// If the specified table_list does not exist, then create
	if(table_id == 0) {
		sprintf(query, "INSERT INTO n_wb_pc_%d (record) VALUES ('%s')",
				this->id, table);
//		printf("query is '%s'\n", query);

		// -- Thread-Safe Mysql call --
		// Request ownership of mutex
		WaitForSingleObject(this->hMutex, INFINITE);
		// Make mysql calls which need Mutex protection
		mysql_query(this->db_link, query);
		rUpdate = mysql_store_result(this->db_link);
		// Release the mutex
		ReleaseMutex(this->hMutex);
		// free up the result from the mysql query
		mysql_free_result(rUpdate);

		// obtain insert id
		int insert_id = mysql_insert_id(this->db_link);

		// now create the new list table
		sprintf(query, "CREATE TABLE IF NOT EXISTS n_wb_pc_%d_%d (", this->id, insert_id);
		strcat(query, "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY");
		strcat(query, ", data VARCHAR(256)");
		strcat(query, ", value VARCHAR(256)");
		strcat(query, ")");

		// -- Thread-Safe Mysql call --
		// Request ownership of mutex
		WaitForSingleObject(this->hMutex, INFINITE);
		// Make mysql calls which need Mutex protection
		mysql_query(this->db_link, query);
		rUpdate = mysql_store_result(this->db_link);
		// Release the mutex
		ReleaseMutex(this->hMutex);
		// free up the result from the mysql query
		mysql_free_result(rUpdate);

		// query for the table_id
		sprintf(query, "SELECT id FROM n_wb_pc_%d WHERE record LIKE \"%%%s%%\"", this->id, table);
//		printf("query is '%s'\n", query);

		// now load up the table id like we were trying before
		// -- Thread-Safe Mysql call --
		// Request ownership of mutex
		WaitForSingleObject(this->hMutex, INFINITE);
		// Make mysql calls which need Mutex protection
		mysql_query(this->db_link, query);
		rSelect = mysql_store_result(this->db_link);
		// Release the mutex
		ReleaseMutex(this->hMutex);

		if(rSelect) {
			if(row = mysql_fetch_row(rSelect)) {
				table_id = atoi(row[0]);
			}

			// free up the result from the mysql query
			mysql_free_result(rSelect);
		}
	}

	// check to see if already exists, add if not
	sprintf(query, "SELECT id FROM n_wb_pc_%d_%d WHERE data='%s'", this->id, table_id, data);
//	printf("query is '%s'\n", query);

	// -- Thread-Safe Mysql call --
	// Request ownership of mutex
	WaitForSingleObject(this->hMutex, INFINITE);
	// Make mysql calls which need Mutex protection
	mysql_query(this->db_link, query);
	rSelect = mysql_store_result(this->db_link);
	// Release the mutex
	ReleaseMutex(this->hMutex);

	bool done = false;
	if(rSelect) {
		if(mysql_num_rows(rSelect) != 0) {
			if(row = mysql_fetch_row(rSelect)) {
				// Data exists, perform an update instead of an insert

				sprintf(query, "UPDATE n_wb_pc_%d_%d SET data='%s', value='%s' WHERE id=%s",
						this->id, table_id, data, value, row[0]);
//				printf("query is '%s'\n", query);

				// -- Thread-Safe Mysql call --
				// Request ownership of mutex
				WaitForSingleObject(this->hMutex, INFINITE);
				// Make mysql calls which need Mutex protection
				mysql_query(this->db_link, query);
				rUpdate = mysql_store_result(this->db_link);
				// Release the mutex
				ReleaseMutex(this->hMutex);
				// free up the result from the mysql query
				mysql_free_result(rUpdate);

				done = true;
			}
		}

		// free up the result from the mysql query
		mysql_free_result(rSelect);
	}

	// pc not found, add
	if(!done) {
		// also save to the database
		sprintf(query, "INSERT INTO n_wb_pc_%d_%d (data, value) VALUES ('%s', '%s')",
				this->id, table_id, data, value);
//		printf("query is '%s'\n", query);

		// -- Thread-Safe Mysql call --
		// Request ownership of mutex
		WaitForSingleObject(this->hMutex, INFINITE);
		// Make mysql calls which need Mutex protection
		mysql_query(this->db_link, query);
		rUpdate = mysql_store_result(this->db_link);
		// Release the mutex
		ReleaseMutex(this->hMutex);
		// free up the result from the mysql query
		mysql_free_result(rUpdate);

		done = true;
	}

	return done;
}

bool Pc::get(char *list, char *data, char *value) {
	MYSQL_RES *rSelect;
	MYSQL_ROW row;
	char query[DEFAULT_BUFLEN];
	char *table;

	// allocate table name to work with
	if(list == NULL) {
		table = _strdup("default");
	}
	else {
		table = _strdup(list);		
	}
	
	// query for the table_id
	sprintf(query, "SELECT id FROM n_wb_pc_%d WHERE record LIKE \"%%%s%%\"", this->id, table);

	// -- Thread-Safe Mysql call --
	// Request ownership of mutex
	WaitForSingleObject(this->hMutex, INFINITE);
	// Make mysql calls which need Mutex protection
	mysql_query(this->db_link, query);
	rSelect = mysql_store_result(this->db_link);
	// Release the mutex
	ReleaseMutex(this->hMutex);

	int table_id = 0;
	if(rSelect) {
		if(row = mysql_fetch_row(rSelect)) {
			table_id = atoi(row[0]);
		}

		// free up the result from the mysql query
		mysql_free_result(rSelect);
	}

	if(table_id != 0) {
		// query for the table_id
		sprintf(query, "SELECT value FROM n_wb_pc_%d_%d WHERE data='%s'", this->id, table_id, data);

		// -- Thread-Safe Mysql call --
		// Request ownership of mutex
		WaitForSingleObject(this->hMutex, INFINITE);
		// Make mysql calls which need Mutex protection
		mysql_query(this->db_link, query);
		rSelect = mysql_store_result(this->db_link);
		// Release the mutex
		ReleaseMutex(this->hMutex);
		
		if(row = mysql_fetch_row(rSelect)) {
			printf("Copying into passed in value '%s'\n", row[0]);
			strcpy(value, row[0]);
		}

		// free up the result from the mysql query
		mysql_free_result(rSelect);

		// free up allocated memory
		delete[] table;

		return true;
	}

	// free up allocated memory
	delete[] table;

	return false;
}